/*
 * @Author: llch
 * @Date: 2020-09-18 10:02:50
 * @LastEditTime: 2021-04-19 16:01:12
 * @LastEditors: Please set LastEditors
 * @Description: 贝塞尔曲线获取路径
 * @FilePath: \tower_defense_demo\assets\scripts\common\gen_map_path.ts
 */

import { UG } from "../modules/ugame"
import { MAP2 } from "../game_data/map_data/map_2";

const {ccclass, property} = cc._decorator;

@ccclass
export default class GenMapPath extends cc.Component {

    @property(cc.Boolean)
    public is_debug: boolean = true;       // 显示调试信息
    @property(cc.Animation)
    public anim_com: cc.Animation = null;   // 动画组件
    @property(cc.Graphics)
    public ctx: cc.Graphics = null;         // 画笔

    public road_data_set = [];

    onLoad () {

        // 不重复生成了，这里直接生成一次地图数据，保存即可
        this.road_data_set = MAP2;
        UG.set_map_road_data(this.road_data_set);

        // let clips: Array<cc.AnimationClip> = this.anim_com.getClips();
        // let clip: cc.AnimationClip = clips[0];
        // let paths = clip.curveData.paths;

        // for (let k in paths) {
        //     let road_data: Array<object> = paths[k].props.position;
        //     this.gen_path_data(road_data);
        // }

        // UG.set_map_road_data(this.road_data_set);
    }

    // 获取地图路径数据
    public get_road_set() {
        return this.road_data_set
    }

    public gen_path_data(road_data): void {
        let ctrl1: cc.Vec2 = undefined;
        let ctrl2: cc.Vec2 = undefined;
        let start_point: cc.Vec2 = undefined;
        let end_point: cc.Vec2 = undefined;

        let road_curve_path = [];
        for (let i = 0; i < road_data.length; i++) {
            let key_frame = road_data[i];
            if (ctrl1 !== undefined) {
                road_curve_path.push([start_point, ctrl1, ctrl1 , cc.v2(key_frame.value[0], key_frame.value[1])]);
            }
            start_point = cc.v2(key_frame.value[0], key_frame.value[1]);
            for (let j = 0; j < key_frame.motionPath.length; j++) {
                let end_point: cc.Vec2 = cc.v2(key_frame.motionPath[j][0], key_frame.motionPath[j][1]);
                ctrl2 = cc.v2(key_frame.motionPath[j][2], key_frame.motionPath[j][3]);
                if (ctrl1 === undefined) {
                    ctrl1 = ctrl2;
                }
                // 贝塞尔曲线 start_point, ctrl1, ctrl2, end_point,
                road_curve_path.push([start_point, ctrl1, ctrl2, end_point]);
                ctrl1 = cc.v2(key_frame.motionPath[j][4], key_frame.motionPath[j][5]);
                start_point = end_point;
            }
        }

        let one_road : Array<cc.Vec2> = [road_curve_path[0][0]];
        // 拿到贝塞尔曲线所有点，计算贝塞尔长度
        for (let index = 0; index < road_curve_path.length; index++) {
            start_point = road_curve_path[index][0];
            ctrl1 = road_curve_path[index][1];
            ctrl2 = road_curve_path[index][2];
            end_point = road_curve_path[index][3];

            let len: number = this._bezier_length(start_point, ctrl1, ctrl2, end_point);
            // offset 计算每两个点之间间隔的点数 
            const OFFSET = 20;
            let count: number = Math.floor(len / OFFSET); 
            // 间隔时间
            let t_delta = 1 / count;
            let t = t_delta;

            for(var i = 0; i < count; i ++) {
                var x = start_point.x * (1 - t) * (1 - t) * (1 - t) + 3 * ctrl1.x * t * (1 - t) * (1 - t) + 3 * ctrl2.x * t * t * (1 - t) + end_point.x * t * t * t;
                var y = start_point.y * (1 - t) * (1 - t) * (1 - t) + 3 * ctrl1.y * t * (1 - t) * (1 - t) + 3 * ctrl2.y * t * t * (1 - t) + end_point.y * t * t * t;
                one_road.push(cc.v2(x, y));
                t += t_delta;
            }
        }

        if (this.is_debug) {
            for (let i = 0; i < one_road.length; i++) {
                this.ctx.moveTo(one_road[i].x, one_road[i].y);
                this.ctx.circle(one_road[i].x, one_road[i].y, 2);
                this.ctx.fillColor = cc.Color.RED;
                this.ctx.fill();
            }
        }

        this.road_data_set.push(one_road);
    }

    // 计算贝塞尔长度
    private _bezier_length(start_point: cc.Vec2, ctrl1: cc.Vec2, ctrl2: cc.Vec2, end_point: cc.Vec2): number {
        // t [0, 1] t 分成20等分 1 / 20 = 0.05
        let prev_point: cc.Vec2 = start_point;
        let length: number = 0;
        let t: number = 0.05;
        for (let i = 0; i < 20; i++) {
            let x = start_point.x * (1 - t) * (1 - t) * (1 - t) + 3 * ctrl1.x * t * (1 - t) * (1 - t) + 3 * ctrl2.x * t * t * (1 - t) + end_point.x * t * t * t;
            let y = start_point.y * (1 - t) * (1 - t) * (1 - t) + 3 * ctrl1.y * t * (1 - t) * (1 - t) + 3 * ctrl2.y * t * t * (1 - t) + end_point.y * t * t * t;
            let now_point: cc.Vec2 = cc.v2(x, y);
            // 两个向量的差值
            let dir: cc.Vec2 = now_point.sub(prev_point)
            // 向量长度
            prev_point = now_point;
            length += dir.mag();

            t += 0.05;
        }
        return length;
    }

}